package com.cooper.controllers.buyer;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.Cookie;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.cooper.constants.ResourceConstants;
import com.cooper.core.JsonResult;
import com.cooper.domain.CartItem;
import com.cooper.entity.SendAddressEntity;
import com.cooper.entity.ShopCartEntity;
import com.cooper.entity.UserInfo;
import com.cooper.pagination.PageInfo;
import com.cooper.pagination.PageResult;
import com.cooper.service.account.SendAddressService;
import com.cooper.service.project.ShopCartService;
import com.cooper.util.BeanUtils;
import com.cooper.util.Controllers;
import com.cooper.vo.AddressSearchVo;
import com.cooper.vo.CompositeShopCartItemVo;
import com.cooper.vo.SendAddressVo;
import com.google.common.collect.Lists;

import net.paoding.rose.web.Invocation;
import net.paoding.rose.web.annotation.Param;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.annotation.rest.Post;
import net.paoding.rose.web.portal.Portal;

public class CartController {

	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	
	private static int ADDRESS_ITEMS_IN_CART = 3;
	
	private final String SHOP_CART_COOKIE = "shop_cart_cookie";
	private final String IS_SHOP_CART_SYNC = "is_shop_cart_sync";
	
	@Autowired
	private ShopCartService shopCartService;
	
	@Autowired
	private SendAddressService sendAddressService;
	
	@Get
	public String execute(Invocation inv, Portal portal) throws Exception{
		this.prepareCartInformation(inv);
		return "Cart";
	}
	
	@Get("panel")
	public String panel(Invocation inv) throws Exception{
		this.prepareCartInformation(inv);
		return "CartPanel";
	}
	
	private void prepareCartInformation(Invocation inv) throws Exception{
		CompositeShopCartItemVo queryParamVo = new CompositeShopCartItemVo();
		UserInfo userInfo = Controllers.getUserInfo(inv);
		if(userInfo!=null){
			String sessionId = "";
			boolean isNeedSync = true;
			queryParamVo.setUserId(userInfo.getId());
			Cookie[] cookies = inv.getRequest().getCookies();
			if(cookies!=null&&cookies.length>0){
				for(Cookie cookie:cookies){
					if(IS_SHOP_CART_SYNC.equals(cookie.getName())&&"y".equals(cookie.getValue())){
						isNeedSync = false;
					}
					if(SHOP_CART_COOKIE.equals(cookie.getName())&&StringUtils.isNotEmpty(cookie.getValue())){
						sessionId = cookie.getValue();
					}
				}
			}
			if(isNeedSync&&StringUtils.isNotEmpty(sessionId)){
			    Cookie c = new Cookie(IS_SHOP_CART_SYNC, "y");
			    inv.getResponse().addCookie(c);
				shopCartService.updateUserIdByCookie(userInfo.getId(), sessionId);
			}
		}else{
			Cookie[] cookies = inv.getRequest().getCookies();
			if(cookies!=null&&cookies.length>0){
				for(Cookie cookie:cookies){
					if(SHOP_CART_COOKIE.equals(cookie.getName())&&StringUtils.isNotEmpty(cookie.getValue())){
						queryParamVo.setCookie(cookie.getValue());
					}
				}
			}
		}
		
		PageInfo pageInfo = new PageInfo();
		pageInfo.setPageSize(100);
		PageResult<CompositeShopCartItemVo>  ret =  shopCartService.findCompositeShopCarts(queryParamVo, pageInfo);
		double totalPrice = 0;
		int totalNum = 0;
		if(ret!=null&&ret.getResult()!=null){
			inv.addModel("shopCartList", ret.getResult());
			totalNum = ret.getResult().size();
			for(CompositeShopCartItemVo itemVo:ret.getResult()){
				totalPrice = totalPrice + itemVo.getPrice() * itemVo.getQuantity();
			}
		}
		inv.addModel("totalNum", totalNum);
		inv.addModel("totalPrice", totalPrice);
	}
	
	
	@Post("add")
	public Object add(Invocation inv,ShopCartEntity shopCart) throws Exception{
		JsonResult json = new JsonResult();
		if(null == shopCart.getItemId() || 0 >= shopCart.getItemId()){
			json.setMessage("Please select item first!");
		} else if(null == shopCart.getSkuId() || 0 >= shopCart.getSkuId()){
			json.setMessage("Please select package first!");
		} else if(null == shopCart.getQuantity() || 0 >= shopCart.getQuantity()){
			json.setMessage("Please check if the sum value is valid!");
		}
		if(StringUtils.isNotBlank(json.getMessage())){
			return json;
		}
		
		String sessionId = "";
		UserInfo userInfo = Controllers.getUserInfo(inv);
		Controllers.prepareEntityForDataSaving(shopCart, userInfo, false);
		
		if(userInfo!=null){
			shopCart.setUserId(userInfo.getId());
		}else{
			Cookie[] cookies = inv.getRequest().getCookies();
			boolean isNeadAdd = true;
			if(cookies!=null&&cookies.length>0){
				for(Cookie cookie:cookies){
					if(SHOP_CART_COOKIE.equals(cookie.getName())&&StringUtils.isNotEmpty(cookie.getValue())){
						sessionId = cookie.getValue();
						isNeadAdd = false;
					}
				}
			}
			if(isNeadAdd){
				sessionId = inv.getRequest().getSession().getId();
				Cookie cookieAdd = new Cookie(SHOP_CART_COOKIE,sessionId);
				inv.getResponse().addCookie(cookieAdd);
			}
			Cookie c = new Cookie(IS_SHOP_CART_SYNC, "n");
			inv.getResponse().addCookie(c);
		}
		
		shopCart.setCookie(sessionId);
		
		try{
			shopCartService.createShopCart(shopCart);
			json.setSuccess(true);
		}catch(Exception e){
			json.setMessage(e.getMessage());
			e.printStackTrace();
		}
		return json;
	}
	
	@Post("saveQuantity")
	public Object saveQuantity(Invocation inv,@Param("cartId") Long id,@Param("quantity") Integer quantity) throws Exception{
		JsonResult json = new JsonResult();
		ShopCartEntity cart = shopCartService.findShopCartById(id);
		UserInfo userInfo = Controllers.getUserInfo(inv);
		Controllers.prepareEntityForDataSaving(cart, userInfo, true);
		if(cart!=null){
			cart.setQuantity(quantity);
		}
		try{
			shopCartService.updateShopCart(cart);
			json.setSuccess(true);
		}catch(Exception e){
			json.setMessage(e.getMessage());
			e.printStackTrace();
		}
		
		return json;
	}
	
	@Post("remove")
	public Object remove(Invocation inv,@Param("cartId") Long id) throws Exception{
		JsonResult json = new JsonResult();
		try{
			if(id!=null){
				shopCartService.removeShopCart(id);
			}
			json.setSuccess(true);
		}catch(Exception e){
			json.setMessage(e.getMessage());
			e.printStackTrace();
		}
		return json;
	}
	
	@Post("removeIds")
	public Object remove(Invocation inv,@Param("selectedCartIds") String selectedCartIds) throws Exception{
		JsonResult json = new JsonResult();
		try{
			if(StringUtils.isNotEmpty(selectedCartIds)){
				List<Long> temp = new ArrayList<Long>();
				for(String str:selectedCartIds.split(",")){
					if(StringUtils.isNotEmpty(str)){
						temp.add(new Long(str));
					}
				}
				shopCartService.removeShopCart(temp);
			}
			json.setSuccess(true);
		}catch(Exception e){
			json.setMessage(e.getMessage());
			e.printStackTrace();
		}
		return json;
	}
	
	@Get("address") @Post("submitCart")
	public String submitCart(Invocation inv, PageInfo pageInfo, AddressSearchVo searchVo) throws Exception{
		UserInfo userInfo = Controllers.getUserInfo(inv);
		searchVo.setOrigin(ResourceConstants.AddressOrigin.RECEIVE_ADDRESS);
		searchVo.setOuterId(userInfo.getId());
		
		pageInfo.setPageSize(ADDRESS_ITEMS_IN_CART);
		PageResult<SendAddressEntity> pageResult = this.sendAddressService.queryForList(searchVo, pageInfo);
		inv.addModel("entityList", pageResult.getResult());
		
		inv.addModel("strCartItems", inv.getParameter("strCartItems"));
		return "CartAddress";
	}
	
	@Get("balance") @Post("submitAddress")
	public String submitAddress(Invocation inv, SendAddressVo addressVo, @Param("addressId") long addressId) throws Exception {
		String strCartItems = inv.getParameter("strCartItems");
		double totalPrice = 0;
		if(StringUtils.isNotBlank(strCartItems)){
			List<CartItem> cartItems = JSON.parseArray(strCartItems, CartItem.class);
			List<CompositeShopCartItemVo> shopCarts = this.convertCartItems2ShopCart(cartItems);
			for(CompositeShopCartItemVo itemVo: shopCarts){
				totalPrice = totalPrice + itemVo.getPrice() * itemVo.getQuantity();
			}
			inv.addModel("cartItems", shopCarts);
		}
		if(0 < addressId){
			SendAddressEntity addressEntity = this.sendAddressService.loadById(addressId);
			BeanUtils.copyProperties(addressEntity, addressVo);
		} else {
			addressVo.setId(addressId);
		}
		inv.addModel("totalPrice", totalPrice);
		inv.addModel("addressVo", addressVo);
		inv.addModel("strAddressVo", JSON.toJSONString(addressVo));
		return "CartBalance";
	}
	
	private List<CompositeShopCartItemVo> convertCartItems2ShopCart(List<CartItem> cartItems) throws Exception{
		List<CompositeShopCartItemVo> retList = Lists.newArrayList();
		if(CollectionUtils.isNotEmpty(cartItems)){
			for(CartItem cartItem: cartItems){
				CompositeShopCartItemVo cartVo = this.shopCartService.getCompositeShopCart(cartItem.getItemId(), cartItem.getSkuId());
				if(null != cartVo){
					cartVo.setQuantity(cartItem.getQuantity());
					retList.add(cartVo);
				}
			}
		}
		return retList;
	}
	
	@Get("cash")
	public String cash(Invocation inv) throws Exception {
		
		return "cash";
	}
}
